package com.ndphu.comic.gui.fragment.searchbook;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.TextView;

import com.ndphu.comic.R;
import com.ndphu.comic.gui.activity.MainActivity;
import com.ndphu.comic.gui.list.adapter.SearchBookItemAdapter;
import com.ndphu.comic.gui.list.model.SearchBookItem;
import com.ndphu.comic.io.Utils;
import com.ndphu.comic.io.extend.AsyncTask;
import com.ndphu.comic.io.processor.Manga24hProcessor;
import com.ndphu.comic.io.processor.TruyenTranhTuanProcessor;
import com.ndphu.comic.io.processor.VNSharingProcessor;
import com.ndphu.comic.model.Book;
import com.ndphu.comic.model.BookEntry;

public class FragmentOnlineSearch extends AbstractSearchBookFragment implements OnItemClickListener, OnClickListener {

	private static final String PREF_SEARCH = "pref_search";
	private static final String PREF_SEARCH_METHOD = "pref_search_method";
	private static final String PREF_SEARCH_MATCH_MODE = "pref_search_match_mode";
	private static final String PREF_SEARCH_SOURCE_VNSHARING = "pref_search_source_vnsharing";
	private static final String PREF_SEARCH_SOURCE_TRUYENTRANHTUAN = "pref_search_source_truyentranhtuan";
	private static final String PREF_SEARCH_SOURCE_MANGA24H = "pref_search_source_manga24h";
	private static final int MATCH_MODE_STARTS_WITH = 0;
	private static final int MATCH_MODE_CONTAINS = 1;
	private static final int METHOD_ONLINE = 0;
	private static final int METHOD_OFFLINE = 1;
	TextWatcher mTextWatcher = new TextWatcher() {

		@Override
		public void onTextChanged(CharSequence s, int start, int before, int count) {

		}

		@Override
		public void beforeTextChanged(CharSequence s, int start, int count, int after) {

		}

		@Override
		public void afterTextChanged(Editable s) {
			// final String searchString = s.toString();
			// if (searchString.isEmpty()) {
			// mPrefPanel.setVisibility(View.VISIBLE);
			// } else{
			// mPrefPanel.setVisibility(View.GONE);
			// }
			// mResultGrid.setVisibility(View.GONE);
			// mResultList.setVelocityScale(View.VISIBLE);
			// doFilter(searchString);
		}
	};

	private static Map<String, Bitmap> mCachedBitmaps = new HashMap<String, Bitmap>();
	private SharedPreferences mImageCachePref;
	private List<String> mLoading = new ArrayList<String>();

	private GridViewAdapter mGridViewAdatper;

	private ListView mResultList;
	private SearchBookItemAdapter mResultListAdapter;

	private GridView mResultGrid;

	private LinearLayout mPrefPanel;

	private EditText mSearchValue;

	private RadioGroup mRadioGroupMethod;
	private RadioGroup mRadioGroupMatchMode;

	private CheckBox mVNSharing;
	private CheckBox mTruyenTranhTuan;
	private CheckBox mManga24h;

	private int mMatchMode;
	private int mMethod;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		mImageCachePref = getActivity().getSharedPreferences(MainActivity.PREF_IMAGE_CACHE, Context.MODE_APPEND);

		View view = inflater.inflate(R.layout.fragment_online_books_search, container, false);
		view.findViewById(R.id.fragment_online_books_search_btn_search).setOnClickListener(this);

		mPrefPanel = (LinearLayout) view.findViewById(R.id.fragment_online_books_search_pref_panel);

		mRadioGroupMethod = (RadioGroup) mPrefPanel
				.findViewById(R.id.fragment_online_books_search_radio_group_search_method);

		mRadioGroupMatchMode = (RadioGroup) mPrefPanel
				.findViewById(R.id.fragment_online_books_search_radio_group_match_mode);

		mResultList = (ListView) view.findViewById(R.id.fragment_online_books_search_list_result);
		mResultList.setDivider(null);
		mResultList.setDividerHeight(0);
		mResultListAdapter = new SearchBookItemAdapter(getActivity(), 0);
		mResultList.setAdapter(mResultListAdapter);
		mResultList.setOnItemClickListener(this);

		mResultGrid = (GridView) view.findViewById(R.id.fragment_online_books_search_grid_result);
		mGridViewAdatper = new GridViewAdapter(getActivity(), 0);
		mResultGrid.setAdapter(mGridViewAdatper);
		mResultGrid.setOnItemClickListener(this);

		mVNSharing = (CheckBox) view.findViewById(R.id.fragment_online_books_search_cb_vnsharing);
		mTruyenTranhTuan = (CheckBox) view.findViewById(R.id.fragment_online_books_search_cb_truyentranhtuan);
		mManga24h = (CheckBox) view.findViewById(R.id.fragment_online_books_search_cb_manga24h);

		mSearchValue = (EditText) view.findViewById(R.id.fragment_online_books_search_search_value);
		mSearchValue.addTextChangedListener(mTextWatcher);
		return view;
	}

	@Override
	public void onDetach() {
		saveToPreferences();
		super.onDetach();
	}

	private void saveToPreferences() {
		System.out.println("Save to pref");
		SharedPreferences settings = getActivity().getSharedPreferences(PREF_SEARCH, Context.MODE_APPEND);
		if (mRadioGroupMethod.getCheckedRadioButtonId() == R.id.fragment_online_books_search_rb_online) {
			mMethod = METHOD_ONLINE;
		} else {
			mMethod = METHOD_OFFLINE;
		}
		if (mRadioGroupMatchMode.getCheckedRadioButtonId() == R.id.fragment_online_books_search_rb_starts_with) {
			mMatchMode = MATCH_MODE_STARTS_WITH;
		} else {
			mMatchMode = MATCH_MODE_CONTAINS;
		}
		settings.edit().remove(PREF_SEARCH_METHOD).putInt(PREF_SEARCH_METHOD, mMethod).remove(PREF_SEARCH_MATCH_MODE)
				.putInt(PREF_SEARCH_MATCH_MODE, mMatchMode).remove(PREF_SEARCH_SOURCE_MANGA24H)
				.putBoolean(PREF_SEARCH_SOURCE_MANGA24H, mManga24h.isChecked())
				.remove(PREF_SEARCH_SOURCE_TRUYENTRANHTUAN)
				.putBoolean(PREF_SEARCH_SOURCE_TRUYENTRANHTUAN, mTruyenTranhTuan.isChecked())
				.remove(PREF_SEARCH_SOURCE_VNSHARING).putBoolean(PREF_SEARCH_SOURCE_VNSHARING, mVNSharing.isChecked())
				.commit();
	}

	private void loadFromPreferences() {
		SharedPreferences settings = getActivity().getSharedPreferences(PREF_SEARCH, Context.MODE_APPEND);
		mMethod = settings.getInt(PREF_SEARCH_METHOD, METHOD_ONLINE);
		mMatchMode = settings.getInt(PREF_SEARCH_MATCH_MODE, MATCH_MODE_STARTS_WITH);
		mRadioGroupMatchMode.check(mMatchMode == MATCH_MODE_CONTAINS ? R.id.fragment_online_books_search_rb_contains
				: R.id.fragment_online_books_search_rb_starts_with);

		mManga24h.setChecked(settings.getBoolean(PREF_SEARCH_SOURCE_MANGA24H, true));
		mTruyenTranhTuan.setChecked(settings.getBoolean(PREF_SEARCH_SOURCE_TRUYENTRANHTUAN, true));
		mVNSharing.setChecked(settings.getBoolean(PREF_SEARCH_SOURCE_VNSHARING, true));
	}

	protected void doOnlineSearch(final String searchString) {
		mGridViewAdatper.clear();
		if (searchString == null || searchString.trim().length() == 0) {
			mGridViewAdatper.clear();
			return;
		}

		new AsyncTask<String, Void, List<SearchBookItem>>() {
			ProgressDialog pd;

			@Override
			protected void onPreExecute() {
				pd = new ProgressDialog(FragmentOnlineSearch.this.getActivity());
				pd.setTitle("Loading");
				pd.setMessage(String.format("Searching \"%s\"...", searchString));
				pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
				pd.setCancelable(false);
				pd.setButton(DialogInterface.BUTTON_NEGATIVE, "Stop", new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						cancel(true);
					}
				});
				pd.setCanceledOnTouchOutside(false);
				pd.show();
			};

			@Override
			protected List<SearchBookItem> doInBackground(String... params) {
				List<SearchBookItem> result = new ArrayList<SearchBookItem>();
				if (FragmentOnlineSearch.this.mManga24h.isChecked()) {
					List<Book> books = new Manga24hProcessor().searchOnline(params[0]);
					for (Book book : books) {
						result.add(new SearchBookItem(book.getName(), "", book.getBookUrl(), "",
								MainActivity.SOURCE_MANGA24H));
					}
				}
				return result;
			}

			protected void onPostExecute(List<SearchBookItem> result) {
				if (pd != null && pd.isShowing()) {
					pd.dismiss();
				}
				
				mPrefPanel.setVisibility(View.GONE);

				for (SearchBookItem item : result) {
					mGridViewAdatper.add(item);
				}
			};

		}.execute(searchString);
	}

	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {
		super.onViewCreated(view, savedInstanceState);
		loadFromPreferences();
	}

	@Override
	public void onItemClick(AdapterView<?> adapter, View view, int position, long arg3) {
		SearchBookItem item = mGridViewAdatper.getItem(position);
		Intent intent = createOpenBookIntent(item);
		getActivity().startActivity(intent);
	}

	public void showAdvanceSearch() {
		if (mPrefPanel.getVisibility() == View.VISIBLE) {
			mPrefPanel.setVisibility(View.GONE);
		} else {
			mPrefPanel.setVisibility(View.VISIBLE);
		}
	}

	@Override
	public void onClick(View view) {
		// mPrefPanel.setVisibility(View.GONE);
		// mResultList.setVisibility(View.GONE);
		// mResultGrid.setVisibility(View.VISIBLE);
		// mGridViewAdatper.clear();
		// for (int i = 0; i < mResultListAdapter.getCount(); ++i) {
		// mGridViewAdatper.add(mResultListAdapter.getItem(i));
		// }
		String queryString = mSearchValue.getText().toString();
		if (mMethod == METHOD_OFFLINE) {
			//doFilter(queryString);
			new AlertDialog.Builder(getActivity()).setTitle("Error").setMessage("Function not implemented").setPositiveButton("OK", new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					
				}
			}).create().show();
		} else {
			doOnlineSearch(queryString);
		}
	}

	public class GridViewAdapter extends ArrayAdapter<SearchBookItem> {

		private LayoutInflater mInflater;
		private Bitmap mWaiting;

		public GridViewAdapter(Context context, int textViewResourceId) {
			super(context, textViewResourceId);
			mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			mWaiting = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if (convertView == null || convertView.getTag() == null || !(convertView.getTag() instanceof ViewHolder)) {
				convertView = mInflater.inflate(R.layout.gridview_searchbook_item, parent, false);
				ViewHolder holder = new ViewHolder();
				holder.cover = (ImageView) convertView.findViewById(R.id.listitem_search_book_item_cover);
				holder.bookName = (TextView) convertView.findViewById(R.id.listitem_search_book_item_book_name);
				holder.bookUrl = (TextView) convertView.findViewById(R.id.listitem_search_book_item_desc);
				convertView.setTag(holder);
			}
			ViewHolder holder = (ViewHolder) convertView.getTag();
			SearchBookItem item = getItem(position);
			fillDataToItem(holder, item);
			return convertView;
		}

		private void fillDataToItem(final ViewHolder holder, final SearchBookItem item) {
			holder.bookName.setText(item.bookName);
			if (item.bookCoverLink == null || item.bookCoverLink.isEmpty()) {
				new AsyncTask<Void, Void, Void>() {

					@Override
					protected Void doInBackground(Void... params) {
						try {
							if (item.bookSource.equals(MainActivity.SOURCE_MANGA24H)) {
								item.bookCoverLink = new Manga24hProcessor().getBookCoverLink(item.bookLink);
							} else if (item.bookSource.equals(MainActivity.SOURCE_TRUYENTRANHTUAN)) {
								item.bookCoverLink = new TruyenTranhTuanProcessor().getBookCoverLink(item.bookLink);
							} else if (item.bookSource.equals(MainActivity.SOURCE_VNSHARING)) {
								item.bookCoverLink = new VNSharingProcessor().getBookCoverLink(item.bookLink);
							}
							holder.bm = getImageFromUrl(item.bookCoverLink);
						} catch (Exception ex) {
							ex.printStackTrace();
						}
						return null;
					}

					protected void onPostExecute(Void result) {
						mGridViewAdatper.notifyDataSetChanged();
					};

				}.execute();
			}
			
			holder.cover.setImageBitmap(holder.bm);
			holder.bookUrl.setText(item.bookLink);
		}

		private Bitmap getImageFromUrl(final String imageUrl) {
			if (imageUrl == null) {
				return mWaiting;
			}
			synchronized (mCachedBitmaps) {
				if (mCachedBitmaps.containsKey(imageUrl)) {
					return mCachedBitmaps.get(imageUrl);
				}
			}
			if (mImageCachePref.contains(imageUrl)) {
				Bitmap bitmap = Utils.decodeFromBase64(mImageCachePref.getString(imageUrl, null));
				synchronized (mCachedBitmaps) {
					mCachedBitmaps.put(imageUrl, bitmap);
				}
				return bitmap;
			} else {
				synchronized (mLoading) {
					if (!mLoading.contains(imageUrl)) {
						mLoading.add(imageUrl);
						new AsyncTask<String, Void, Bitmap>() {
							@Override
							protected Bitmap doInBackground(String... params) {
								try {
									Bitmap bitmap = Utils.getBitmapFromUrl(imageUrl, 480, 480);
									if (bitmap != null) {
										synchronized (mImageCachePref) {
											mImageCachePref.edit().putString(imageUrl, Utils.encodeToBase64(bitmap))
													.commit();
										}
										synchronized (mCachedBitmaps) {
											mCachedBitmaps.put(imageUrl, bitmap);
										}
									}
									return bitmap;
								} catch (Exception e) {
									e.printStackTrace();
								}
								return null;
							}

							protected void onPostExecute(Bitmap result) {
								super.onPostExecute(result);
								synchronized (mLoading) {
									mLoading.remove(imageUrl);
								}
								if (result != null) {
									mGridViewAdatper.notifyDataSetChanged();
								} else {
									synchronized (mImageCachePref) {
										mImageCachePref.edit().putString(imageUrl, Utils.encodeToBase64(mWaiting))
												.commit();
									}
									synchronized (mCachedBitmaps) {

										mCachedBitmaps.put(imageUrl, mWaiting);
									}
								}

							};
						}.execute(imageUrl);
					}
				}
				return mWaiting;
			}
		}

		public class ViewHolder {
			ImageView cover;
			TextView bookName;
			TextView bookUrl;
			Bitmap bm;
		}

	}
}
